home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-09-28 | 37.5 KB | 1,061 lines |
- ╓───────────────╖
- ║ Week 2, Day 1 ║
- ╙───────────────╜
-
- Our RPG will be simple, requiring you to navigate a maze and find the exit.
- To make things more interesting the maze will be populated with creatures that
- attack you.
- Defeat them and you will be rewarded in gold coins.
- Food, weapons and other useful items will be present in some rooms.
- Only one room has the exit but you must pay a toll of 100 gold pieces to use
- it.
-
- Lets begin by defining the maze and letting the player walk through it.
- (Entering "q" during play will stop the program.)
- Type (or edit) and RUN:
-
- CLS
- row = 5
- column = 5
- moveErr$ = "You cannot move in that direction!"
-
- LOCATE 14,1
- PRINT "Commands: n - north"
- PRINT " s - south"
- PRINT " e - east"
- PRINT " w - west"
- PRINT
- PRINT " q - quit"
-
- DO
- LOCATE 1, 1
- PRINT "Your position:"; row; column
- LOCATE 8, 1
- INPUT "What now"; reply$
- LOCATE 10, 1
- PRINT SPACE$(79)
-
- SELECT CASE reply$
- CASE IS = "n"
- IF row = 1 THEN
- LOCATE 10, 1
- PRINT moveErr$
- ELSE
- row = row - 1
- LOCATE 10, 1
- PRINT "You go north."
- END IF
- CASE IS = "s"
- IF row = 10 THEN
- LOCATE 10, 1
- PRINT moveErr$
- ELSE
- row = row + 1
- LOCATE 10, 1
- PRINT "You go south."
- END IF
- CASE IS = "w"
- IF column = 1 THEN
- LOCATE 10, 1
- PRINT moveErr$
- ELSE
- column = column - 1
- LOCATE 10, 1
- PRINT "You go west."
- END IF
- CASE IS = "e"
- IF column = 10 THEN
- LOCATE 10, 1
- PRINT moveErr$
- ELSE
- column = column + 1
- LOCATE 10, 1
- PRINT "You go east."
- END IF
- CASE IS = "q"
- LOCATE 10, 1
- PRINT "Bye!"
- END
- END SELECT
-
- LOOP
-
- You'll notice that the maze is 10 by 10 rooms in size.
- I you try to move outside its boundaries you are stopped and an error message
- appears (I stored it in variable "moveErr$" so there's less typing).
-
- The command INPUT prompts the user for a value and stores it in a variable
- (reply$).
- As a bonus you can display some text at the same time ("What now").
-
- SPACE$ is a function that provides spaces; SPACE$(2) gives you " ".
- What the program does at that point is to overwrite any error messages that
- resulted from the previous user input.
-
- "INT(RND * 10) + 1" gives a whole number ranging from 1 to 10.
- How does it work?
- INT gives the integer value of a variable, e.g. INT(1.9) gives 1.
- Because RND gives a value between 0 and 1, RND * 10 will give a value between
- 0 and 10.
- And because INT(0.99) = 0 and INT(9.99) = 9, it is necessary to add 1 to the
- result.
-
- Now to add an exit to the maze:
-
- CLS
- row = 5
- column = 5
- moveErr$ = "You cannot move in that direction!"
- exitRow = INT(RND * 10) + 1 :REM <─┬─ new
- exitColumn = INT(RND * 10) + 1 :REM │
- gold = 0 :REM ─┘
-
- LOCATE 14, 1
- PRINT "Commands: n - north"
- PRINT " s - south"
- PRINT " e - east"
- PRINT " w - west"
- PRINT " x - use exit" :REM <──- new
- PRINT
- PRINT " q - quit"
-
- DO
- LOCATE 1, 1
- PRINT "Your position:"; row; column
- :REM <─┬─ new
- IF ((row = exitRow) AND (column = exitColumn)) THEN
- LOCATE 2, 1 :REM │
- PRINT "You are at the exit!" :REM │
- ELSE :REM │
- LOCATE 2, 1 :REM │
- PRINT SPACE$(79) :REM │
- END IF :REM ─┘
- LOCATE 8, 1
- INPUT "What now"; reply$
- LOCATE 10, 1
- PRINT SPACE$(79)
-
- SELECT CASE reply$
- CASE IS = "n"
- IF row = 1 THEN
- LOCATE 10, 1
- PRINT moveErr$
- ELSE
- row = row - 1
- LOCATE 10, 1
- PRINT "You go north."
- END IF
- CASE IS = "s"
- IF row = 10 THEN
- LOCATE 10, 1
- PRINT moveErr$
- ELSE
- row = row + 1
- LOCATE 10, 1
- PRINT "You go south."
- END IF
- CASE IS = "w"
- IF column = 1 THEN
- LOCATE 10, 1
- PRINT moveErr$
- ELSE
- column = column - 1
- LOCATE 10, 1
- PRINT "You go west."
- END IF
- CASE IS = "e"
- IF column = 10 THEN
- LOCATE 10, 1
- PRINT moveErr$
- ELSE
- column = column + 1
- LOCATE 10, 1
- PRINT "You go east."
- END IF
- CASE IS = "x" :REM <─┬─ new
- IF ((row = exitRow) AND (column = exitColumn)) THEN
- :REM │
- IF gold < 100 THEN
- LOCATE 10, 1 :REM │
- PRINT "You dont have enough gold!" :REM │
- ELSE :REM │
- LOCATE 10, 1 :REM │
- PRINT "You have escaped! Well done!" :REM │
- END :REM │
- END IF :REM │
- END IF :REM ─┘
- CASE IS = "q"
- LOCATE 10, 1
- PRINT "Bye!"
- END
- END SELECT
-
- LOOP
-
- Thought you could escape?
- Maybe tomorrow when we add monsters and gold!
-
- -------------------------------------------------------------------------------
- ╓───────────────╖
- ║ Week 2, Day 2 ║
- ╙───────────────╜
-
- To make things interesting we'll use RND to scatter a variety of monsters
- throughout the maze.
- The amount of gold present in a room will depend on how difficult the monster
- is to beat.
- Type (or edit) and RUN:
-
- CLS
- DIM monster(10, 10) :REM <─┬- new
- FOR count1 = 1 TO 10 :REM │
- FOR count2 = 1 TO 10 :REM │
- monster(count1, count2) = INT(RND * 11) :REM │
- NEXT count2 :REM │
- NEXT count1 :REM ─┘
-
- row = 5
- column = 5
- moveErr$ = "You cannot move in that direction!"
- exitRow = INT(RND * 10) + 1
- exitColumn = INT(RND * 10) + 1
- gold = 0
-
- DIM monster$(10) :REM <─┬─ new
- RESTORE monsterData :REM │
- FOR count = 1 TO 10 :REM │
- READ monster$(count) :REM │
- NEXT count :REM ─┘
-
- LOCATE 14, 1
- PRINT "Commands: n - north"
- PRINT " s - south"
- PRINT " e - east"
- PRINT " w - west"
- PRINT " x - use exit"
- PRINT
- PRINT " q - quit"
-
- DO
- LOCATE 1, 1
- PRINT "Your position:"; row; column
- IF ((row = exitRow) AND (column = exitColumn)) THEN
- LOCATE 2, 1
- PRINT "You are at the exit!"
- ELSE
- LOCATE 2, 1
- PRINT SPACE$(79)
- END IF
- LOCATE 3, 1 :REM <─┬─ new
- PRINT "Monster: "; :REM │
- monsterType = monster(row, column) :REM │
- IF monsterType = 0 THEN
- PRINT "nothing " :REM │
- ELSE :REM │
- monsterName$ = MID$(monster$(monsterType), 1, 10) :REM │
- PRINT monsterName$ :REM │
- END IF :REM ─┘
-
- LOCATE 8, 1
- INPUT "What now"; reply$
- LOCATE 10, 1
- PRINT SPACE$(79)
-
- SELECT CASE reply$
- CASE IS = "n"
- IF row = 1 THEN
- LOCATE 10, 1
- PRINT moveErr$
- ELSE
- row = row - 1
- LOCATE 10, 1
- PRINT "You go north."
- END IF
- CASE IS = "s"
- IF row = 10 THEN
- LOCATE 10, 1
- PRINT moveErr$
- ELSE
- row = row + 1
- LOCATE 10, 1
- PRINT "You go south."
- END IF
- CASE IS = "w"
- IF column = 1 THEN
- LOCATE 10, 1
- PRINT moveErr$
- ELSE
- column = column - 1
- LOCATE 10, 1
- PRINT "You go west."
- END IF
- CASE IS = "e"
- IF column = 10 THEN
- LOCATE 10, 1
- PRINT moveErr$
- ELSE
- column = column + 1
- LOCATE 10, 1
- PRINT "You go east."
- END IF
- CASE IS = "x"
- IF ((row = exitRow) AND (column = exitColumn)) THEN
- IF gold < 100 THEN
- LOCATE 10, 1
- PRINT "You dont have enough gold!"
- ELSE
- LOCATE 10, 1
- PRINT "You have escaped! Well done!"
- END
- END IF
- END IF
- CASE IS = "q"
- LOCATE 10, 1
- PRINT "Bye!"
- END
- END SELECT
-
- LOOP
-
- monsterData: :REM <─┬─ new
- DATA "blind bat " :REM │
- DATA "rat " :REM │
- DATA "snake " :REM │
- DATA "goblin " :REM │
- DATA "troll " :REM │
- DATA "bear " :REM │
- DATA "lion " :REM │
- DATA "sabretooth" :REM │
- DATA "elephant " :REM │
- DATA "dragon " :REM ─┘
-
- I decided to allocate a number to each room to identify the type of monster in
- the room.
- To do this I needed 10 x 10 numbers.
- If we keep in mind that our player's location is stored as a row and a column
- value, its easy to see why I decided to to use a similar method of storing
- the monster values.
- Just by using row and column ( monster(row, column) ) you get the monster value
- at the player's location.
-
- As you can see at the top of the program, I gave each location a monster value
- ranging from 0 to 10 (remember that INT(RND * 11) never gives 11).
- Why not 1 to 10?
- The 0 will serve as an indicator that there is no monster at that location.
-
- What's RESTORE and READ?
- The READ command looks for DATA statements in your program and reads their
- values (e.g. the names of the monsters).
- It starts at the first DATA statement unless you use RESTORE to point it to
- a specific part of the program.
- RESTORE points to a LABEL (e.g. monsterData).
- You can put LABELS anywhere in your program, just remember to follow it with a
- colon.
-
- Why READ the monster names when you can use: monster$(1) = "blind bat ",
- monster$(2) = "rat ", etc?
- Its just easier to find the data if its grouped together.
- You can then use a FOR..NEXT loop to set the values rather than typing
- monster(x)="abcd" every time.
-
- One last thing about READ: it remembers the position where it last read a value
- , so you have to use RESTORE if you want to read from the top again.
-
- Notice how I use the monster number (monsterType) to display its name from a
- monster$.
- So if monsterType = 1 then monster$(monsterType) = "blind bat " will be
- displayed.
-
- This should be enough reading for one day!
-
- -------------------------------------------------------------------------------
- ╓───────────────╖
- ║ Week 2, Day 3 ║
- ╙───────────────╜
-
- What good are monsters if they dont put up a fight?
- I'll rectify that if you type and RUN:
-
- CLS
- DIM monster(10, 10)
- FOR count1 = 1 TO 10
- FOR count2 = 1 TO 10
- monster(count1, count2) = INT(RND * 11)
- NEXT count2
- NEXT count1
-
- row = 5
- column = 5
- moveErr$ = "You cannot move in that direction!"
- pressKey$ = "Press any key to continue." :REM <──- new
- exitRow = INT(RND * 10) + 1
- exitColumn = INT(RND * 10) + 1
- gold = 0
- health = 20 :REM <─┬─ new
- weapon = 1 :REM ─┘
-
- DIM monster$(10)
- RESTORE monsterData
- FOR count = 1 TO 10
- READ monster$(count)
- NEXT count
-
- LOCATE 14, 1
- PRINT "Commands: n - north"
- PRINT " s - south"
- PRINT " e - east"
- PRINT " w - west"
- PRINT " a - attack" :REM <──- new
- PRINT " x - use exit"
- PRINT
- PRINT " q - quit"
-
- DO
- LOCATE 1, 1
- PRINT "Your position:"; row; column
- LOCATE 1, 25 :REM <─┬─ new
- PRINT "Gold:"; gold; " Health:"; health :REM ─┘
- IF ((row = exitRow) AND (column = exitColumn)) THEN
- LOCATE 2, 1
- PRINT "You are at the exit!"
- ELSE
- LOCATE 2, 1
- PRINT SPACE$(79)
- END IF
- LOCATE 3, 1
- PRINT "Monster: ";
- monsterType = monster(row, column)
- IF monsterType = 0 THEN
- PRINT "nothing "
- ELSE
- monsterName$ = MID$(monster$(monsterType), 1, 10)
- PRINT monsterName$
- monsterAttack = VAL(MID$(monster$(monsterType), 11, 1)) :REM <─┬- new
- monsterHealth = VAL(MID$(monster$(monsterType), 12, 1)) :REM │
- monsterGold = monsterType * INT(RND * 6) :REM ─┘
- END IF
-
- LOCATE 8, 1
- INPUT "What now"; reply$
- LOCATE 10, 1
- PRINT SPACE$(79)
- PRINT SPACE$(79)
- PRINT SPACE$(79)
-
- SELECT CASE reply$
- CASE IS = "n"
- IF row = 1 THEN
- LOCATE 10, 1
- PRINT moveErr$
- ELSE
- row = row - 1
- LOCATE 10, 1
- PRINT "You go north."
- END IF
- CASE IS = "s"
- IF row = 10 THEN
- LOCATE 10, 1
- PRINT moveErr$
- ELSE
- row = row + 1
- LOCATE 10, 1
- PRINT "You go south."
- END IF
- CASE IS = "w"
- IF column = 1 THEN
- LOCATE 10, 1
- PRINT moveErr$
- ELSE
- column = column - 1
- LOCATE 10, 1
- PRINT "You go west."
- END IF
- CASE IS = "e"
- IF column = 10 THEN
- LOCATE 10, 1
- PRINT moveErr$
- ELSE
- column = column + 1
- LOCATE 10, 1
- PRINT "You go east."
- END IF
- CASE IS = "x"
- IF ((row = exitRow) AND (column = exitColumn)) THEN
- IF gold < 100 THEN
- LOCATE 10, 1
- PRINT "You dont have enough gold!"
- ELSE
- LOCATE 10, 1
- PRINT "You have escaped! Well done!"
- END
- END IF
- END IF
- CASE IS = "a" :REM <─┬ new
- IF monsterType = 0 THEN
- LOCATE 10, 1 :REM │
- PRINT "There's nothing to attack!" :REM │
- ELSE :REM │
- DO WHILE ((monsterHealth > 0) AND (health > 0)) :REM │
- LOCATE 10, 1 :REM │
- PRINT SPACE$(79) :REM │
- PRINT SPACE$(79) :REM │
- PRINT SPACE$(79) :REM │
- LOCATE 10, 1 :REM │
- attack = weapon + INT(RND * 9) :REM │
- SELECT CASE attack :REM │
- CASE IS = monsterAttack :REM │
- PRINT "No one wins this round." :REM │
- CASE IS > monsterAttack :REM │
- PRINT "You deal the "; monsterName$; " a blow!":REM │
- monsterHealth = monsterHealth - 1 :REM │
- CASE IS < monsterAttack :REM │
- PRINT "You have been wounded!" :REM │
- health = health - 1 :REM │
- END SELECT :REM │
- PRINT pressKey$ :REM │
- SLEEP :REM │
- LOOP :REM │
- LOCATE 10, 1 :REM │
- IF health > 0 THEN
- PRINT "You won the fight!" :REM │
- PRINT "You found "; monsterGold; " pieces of gold!" :REM │
- gold = gold + monsterGold :REM │
- monsterType = 0 :REM │
- monster(row, column) = 0 :REM │
- PRINT pressKey$ :REM │
- SLEEP :REM │
- ELSE :REM │
- PRINT "The "; monsterName$; " killed you!" :REM │
- PRINT "Game over!" :REM │
- END :REM │
- END IF :REM │
- END IF :REM ─┘
- CASE IS = "q"
- LOCATE 10, 1
- PRINT "Bye!"
- END
- END SELECT
-
- LOOP
-
- monsterData:
- DATA "blind bat 21" :REM <─┬─ changed
- DATA "rat 11" :REM │
- DATA "snake 31" :REM │
- DATA "goblin 23" :REM │
- DATA "troll 44" :REM │
- DATA "bear 55" :REM │
- DATA "lion 54" :REM │
- DATA "sabretooth65" :REM │
- DATA "elephant 78" :REM │
- DATA "dragon 98" :REM ─┘
-
- Starting from the top:
- The variable "health" starts of at 20 but 1 gets subtracted from it each time a
- monster hits you.
- If it reaches 0 you've had it.
- The variable "weapon" gets added to your attack score: weapon + INT(RND * 9).
- So the attack score will range from 1 to 9. (INT(RND * 9) gives 0 to 8)
-
- MonsterAttack: A monster's attack score is stored as the second last character
- in a monster$.
- VAL takes a string and converts it to a decimal value, so VAL("10") gives 10.
- Trying something like VAL("ABC") will cause a runtime error.
-
- MonsterHealth: The last character READ into a monster$ is the monster's health.
- Each time you wound it, it loses a point of health and dies when
- it loses all its points.
-
- MonsterGold: I chose to add a random factor to the amount of gold found, but by
- multiplying with monsterAttack you should still find more gold
- after defeating tougher monsters.
-
- Notice that fighting takes place and continues until one side runs out of
- health.
- So when this loop terminates we know that if your health > 0 then the monster's
- health must have run out.
- If the monster loses then monsterType is set to 0 so that you cannot fight
- it again.
- Monsters(row, column) = 0 changes the location's monster to "nothing", so when
- you enter this location again there will be no monsters.
-
- Can you remember that the SLEEP command is used to pause the program for a
- number of seconds?
- SLEEP on its own waits indefinitely or until a key is pressed.
- I've used it to wait for a keypress.
- You can use DO: LOOP UNTIL INKEY$ <> "" instead of SLEEP.
-
- Thats all for now!
-
- -------------------------------------------------------------------------------
- ╓───────────────╖
- ║ Week 2, Day 4 ║
- ╙───────────────╜
-
- Lets scatter some useful items like food and weapons throughout the maze.
- To balance things we'll add a few traps..
-
- CLS
- RANDOMIZE TIMER :REM <─── new
- DIM monster(10, 10)
- FOR count1 = 1 TO 10
- FOR count2 = 1 TO 10
- monster(count1, count2) = INT(RND * 11)
- NEXT count2
- NEXT count1
-
- DIM item(10, 10) :REM <─┬─ new
- FOR count1 = 1 TO 10 :REM │
- FOR count2 = 1 TO 10 :REM │
- IF RND < .2 THEN :REM │
- item(count1, count2) = INT(RND * 9) + 1 :REM │
- ELSE :REM │
- item(count1, count2) = 0 :REM │
- END IF :REM │
- NEXT count2 :REM │
- NEXT count1 :REM ─┘
-
- row = 5
- column = 5
- moveErr$ = "You cannot move in that direction!"
- pressKey$ = "Press any key to continue."
- exitRow = INT(RND * 10) + 1
- exitColumn = INT(RND * 10) + 1
- gold = 0
- health = 20
- weapon = 1
-
- DIM monster$(10)
- RESTORE monsterData
- FOR count = 1 TO 10
- READ monster$(count)
- NEXT count
-
- DIM item$(9) :REM <─┬─ new
- RESTORE itemData :REM │
- FOR count = 1 TO 9 :REM │
- READ item$(count) :REM │
- NEXT count :REM ─┘
-
- LOCATE 14, 1
- PRINT "Commands: n - north"
- PRINT " s - south"
- PRINT " e - east"
- PRINT " w - west"
- PRINT " a - attack"
- PRINT " t - take item" :REM <─── new
- PRINT " x - use exit"
- PRINT
- PRINT " q - quit"
-
- LOCATE 14, 40 :REM <─┬─ new
- PRINT CHR$(201); STRING$(10, CHR$(205)); CHR$(187) :REM │
- LOCATE 15, 40 :REM │
- PRINT CHR$(186); SPACE$(10); CHR$(186) :REM │
- LOCATE 16, 40 :REM │
- PRINT CHR$(200); STRING$(10, CHR$(205)); CHR$(188) :REM │
- LOCATE 17, 44 :REM │
- PRINT "ITEM" :REM ─┘
-
- DO
- LOCATE 1, 1
- PRINT "Your position:"; row; column
- LOCATE 1, 25
- PRINT "Gold:"; gold; " Health:"; health; " Weapon:"; weapon :REM <──changed
- IF ((row = exitRow) AND (column = exitColumn)) THEN
- LOCATE 2, 1
- PRINT "You are at the exit!"
- ELSE
- LOCATE 2, 1
- PRINT SPACE$(79)
- END IF
- LOCATE 3, 1
- PRINT "Monster: ";
- monsterType = monster(row, column)
- IF monsterType = 0 THEN
- PRINT "nothing "
- ELSE
- monsterName$ = MID$(monster$(monsterType), 1, 10)
- PRINT monsterName$
- monsterAttack = VAL(MID$(monster$(monsterType), 11, 1))
- MonsterHealth = VAL(MID$(monster$(monsterType), 12, 1))
- MonsterGold = monsterType * INT(RND * 6)
- END IF
-
- itemType (or edit) = item(row, column) :REM <─┬─ new
- IF itemType (or edit) = 0 THEN :REM │
- LOCATE 15, 41 :REM │
- PRINT "nothing " :REM │
- ELSE :REM │
- itemName$ = LEFT$(item$(itemType (or edit)), 10) :REM │
- itemClass$ = MID$(item$(itemType (or edit)), 11, 1) :REM │
- itemValue = VAL(RIGHT$(item$(itemType (or edit)), 1)) :REM │
- LOCATE 15, 41 :REM │
- PRINT itemName$ :REM │
- IF itemClass$ = "T" THEN :REM │
- LOCATE 10, 1 :REM │
- PRINT "The "; RTRIM$(itemName$); " damages you for "; itemValue; " points!"
- health = health - itemValue :REM │
- item(row, column) = 0 :REM │
- itemType (or edit) = 0 :REM │
- IF health <= 0 THEN :REM │
- PRINT "You die!" :REM │
- PRINT "Game over!" :REM │
- END :REM │
- END IF :REM │
- END IF :REM │
- END IF :REM ─┘
-
- LOCATE 8, 1
- INPUT "What now"; reply$
- LOCATE 10, 1
- PRINT SPACE$(79)
- PRINT SPACE$(79)
- PRINT SPACE$(79)
-
- SELECT CASE reply$
- CASE IS = "n"
- IF row = 1 THEN
- LOCATE 10, 1
- PRINT moveErr$
- ELSE
- row = row - 1
- LOCATE 10, 1
- PRINT "You go north."
- END IF
- CASE IS = "s"
- IF row = 10 THEN
- LOCATE 10, 1
- PRINT moveErr$
- ELSE
- row = row + 1
- LOCATE 10, 1
- PRINT "You go south."
- END IF
- CASE IS = "w"
- IF column = 1 THEN
- LOCATE 10, 1
- PRINT moveErr$
- ELSE
- column = column - 1
- LOCATE 10, 1
- PRINT "You go west."
- END IF
- CASE IS = "e"
- IF column = 10 THEN
- LOCATE 10, 1
- PRINT moveErr$
- ELSE
- column = column + 1
- LOCATE 10, 1
- PRINT "You go east."
- END IF
- CASE IS = "x"
- IF ((row = exitRow) AND (column = exitColumn)) THEN
- IF gold < 100 THEN
- LOCATE 10, 1
- PRINT "You dont have enough gold!"
- ELSE
- LOCATE 10, 1
- PRINT "You have escaped! Well done!"
- END
- END IF
- END IF
- CASE IS = "a"
- IF monsterType = 0 THEN
- LOCATE 10, 1
- PRINT "There's nothing to attack!"
- ELSE
- DO WHILE ((MonsterHealth > 0) AND (health > 0))
- LOCATE 10, 1
- PRINT SPACE$(79)
- PRINT SPACE$(79)
- PRINT SPACE$(79)
- LOCATE 10, 1
- attack = weapon + INT(RND * 9)
- SELECT CASE attack
- CASE IS = monsterAttack
- PRINT "No one wins this round."
- CASE IS > monsterAttack
- :REM <── changed
- PRINT "You deal the "; RTRIM$(monsterName$); " a blow!"
- :REM ─────┘
- MonsterHealth = MonsterHealth - 1
- CASE IS < monsterAttack
- PRINT "You have been wounded!"
- health = health - 1
- END SELECT
- PRINT pressKey$
- SLEEP
- LOOP
- LOCATE 10, 1
- IF health > 0 THEN
- PRINT "You won the fight!"; SPACE$(20)
- PRINT "You found "; MonsterGold; " pieces of gold!"
- gold = gold + MonsterGold
- monsterType = 0
- monster(row, column) = 0
- PRINT pressKey$
- SLEEP
- ELSE
- :REM <── changed
- PRINT "The "; RTRIM$(monsterName$); " killed you!"; SPACE$(20)
- :REM ─────┘
- PRINT "Game over!"; SPACE$(20)
- END
- END IF
- END IF
- CASE IS = "t" :REM <─┐new
- IF itemType (or edit) = 0 THEN :REM │
- LOCATE 10, 1 :REM │
- PRINT "Nothing to take!" :REM │
- PRINT pressKey$ :REM │
- SLEEP :REM │
- ELSE :REM │
- SELECT CASE itemClass$ :REM │
- CASE IS = "F" :REM │
- LOCATE 10, 1 :REM │
- PRINT "You eat the "; RTRIM$(itemName$); "." :REM │
- IF health = 20 THEN :REM │
- PRINT "You had no wounds, so the food is wasted." :REM │
- ELSE :REM │
- health = health + itemValue :REM │
- PRINT "You gain "; itemValue; " health points." :REM │
- END IF :REM │
- CASE IS = "W" :REM │
- LOCATE 10, 1 :REM │
- IF weapon >= itemValue THEN :REM │
- PRINT "You have a similar or better weapon." :REM │
- ELSE :REM │
- PRINT "You pick up a "; RTRIM$(itemName$); " !" :REM │
- weapon = itemValue :REM │
- PRINT "Your weapon rating is now "; weapon; "." :REM │
- END IF :REM │
- END SELECT :REM │
- PRINT pressKey$ :REM │
- SLEEP :REM │
- item(row, column) = 0 :REM │
- itemType (or edit) = 0 :REM │
- END IF :REM ─┘
- CASE IS = "q"
- LOCATE 10, 1
- PRINT "Bye!"
- END
- END SELECT
-
- LOOP
-
- monsterData:
- DATA "blind bat 21"
- DATA "rat 11"
- DATA "snake 31"
- DATA "goblin 23"
- DATA "troll 44"
- DATA "bear 55"
- DATA "lion 54"
- DATA "sabretooth65"
- DATA "elephant 78"
- DATA "dragon 98"
-
- itemData: :REM <─┬─ new
- DATA "apple F1" :REM │
- DATA "bread F2" :REM │
- DATA "chicken F3" :REM │
- DATA "dagger W2" :REM │
- DATA "sword W3" :REM │
- DATA "halberd W4" :REM │
- DATA "smoke T1" :REM │
- DATA "noose trapT2" :REM │
- DATA "pit trap T3" :REM ─┘
-
- Starting from the top:
- You have probably noticed that, although RND gives random effects, you keep
- getting the same set of random values!
- This is because the computer uses a base value (called a "seed") to start
- calculating RND.
- RANDOMIZE sets the "seed" to a new value so the RNDs will be different.
- The value of TIMER is the amount of seconds since midnight.
- Because this value keeps changing we use it as a "seed" in the expression
- RANDOMIZE TIMER.
-
- Items are addressed by using the array item(10, 10), allowing for one item
- per room in the maze.
- There's only a 20% chance of a room having an item (RND < .2) and then the
- item is identified by a number ranging from 1 to 9.
- More data on the 9 different item types is READ into item$.
-
- CHR$ is used to convert an ASCII value into a character.
- So instead of doing PRINT "A", we can use PRINT CHR$(65), 65 being its ASCII
- value.
- By using CHR$ we can access some nice characters for graphical purposes.
- To view these characters in QBasic: Press SHIFT-F1. Choose the "Contents" box,
- then choose the "ASCII character codes" box.
- The character with ASCII value 2 would make a nice PACMAN.
-
- Each "item" has a name, class and value.
- The class shows whether its food ("F"), a weapon ("W"), or a trap("T").
- The value is used differently for each class:
- class: food Value: number of health points gained by player
- weapon new "weapon" value for player
- trap number of health points player will lose
-
- LEFT$(a$, 10) is the same as MID$(a$, 1, 10), in other words it just starts
- at the first position in the string.
- RIGHT$("ABCDE", 3) gives "CDE", in other words it takes the rightmost 3
- characters.
- You can use MID$ instead of LEFT$ and RIGHT$, but its possible to save time by
- using them.
-
- The "trap" item immediately damages the player upon entering the room.
- The trap is then disabled by removing it from the array (item(row, column) = 0)
-
- RTRIM$("ABC ") gives "ABC", in other words it removes the spaces on the right.
- LTRIM$ work in the same way, but removes spaces from the left.
-
- I added some interesting checks for when a player takes an item.
- If he takes food and he has no wounds (health = 20), the food goes to waste.
- If he tries to take a weapon thats rated worse or the same as his present
- weapon, he is stopped.
-
- This concludes our RPG.
- Tomorrow I'll illustrate a few commands for generating graphics.
-
- -------------------------------------------------------------------------------
- ╓───────────────╖
- ║ Week 2, Day 5 ║
- ╙───────────────╜
-
- I'll demonstrate manipulation of a simple graphic by putting the screen in
- graphics mode (its usually in text mode), drawing the graphic, grabbing it
- from the screen and storing it in an array, displaying it again from the array
- while shifting its position from the left to the right of the screen.
- (I have a long breath!)
- Here goes:
-
- REM SCREEN mode number
- REM 1 = CGA 320x200, 4 colors Graphics mode
- SCREEN 1
-
- REM COLOR palette number, background color
- REM 0 -> black, green, red, brown 0 to 15
- REM 1 -> black, cyan, magenta, white
- REM color = 0 1 2 3
- COLOR 0, 1
-
- xDim = 16: REM The width of the image in pixels
- yDim = 16: REM The height of the imgae in pixels
-
- REM Use this formula for calculating the size of the array needed to store
- REM the image. The size is measured in bytes.
- size = 4 + INT(((xDim + 1) * 2 + 7) / 8) * (yDim + 1)
-
- DIM pic(size / 2) AS INTEGER: REM An INTEGER is two bytes in size
-
- REM Draw a block 14x14 pixels in size and fill it.
- REM LINE (startX, startY)-(endX, endY), color, BF=block fill
- REM The entire screen starts at (0, 0) and ends at (319, 199)
- LINE (1, 1)-(14, 14), 1, BF
-
- REM Get a 16x16 image from the screen and store it in the array pic.
- GET (0, 0)-(15, 15), pic
-
- CLS
-
- FOR count = 0 TO 320 - 16
- REM Put the image on the screen. PSET makes it overwrite the previous image.
- PUT (count, 90), pic, PSET
- REM Slow down the computer. Make the value bigger if its still too fast.
- FOR nothing = 1 TO 100
- NEXT nothing
- NEXT count
-
- END
-
- The REMs explain nearly everything.
- Experiment with colors by choosing one of the two sets (four colors in each
- set) by modifying the COLOR statement.
- Then choose between the four available colors by modifying the LINE statement.
-
- Why did I draw a 14x14 image but stored it as a 16x16 image?
- That way the stored image is surrounded by a "frame" of black dots.
- When moving the image around, the black "frame" deletes the previous (old)
- image.
- So I'm displaying the image in its new position and deleting the old image at
- the same time!
-
- You could make more interesting images by using the PSET command which places
- dots on the screen.
- Type (or edit) and RUN:
-
- SCREEN 1
- COLOR 0, 1
-
- xDim = 8
- yDim = 8
-
- size = 4 + INT(((xDim + 1) * 2 + 7) / 8) * (yDim + 1)
-
- DIM pic(size / 2) AS INTEGER
-
- RESTORE pacmanPic
- FOR row = 1 TO yDim
- FOR column = 1 TO xDim
- READ picData
- PSET (column, row), picData
- NEXT column
- NEXT row
-
- GET (0, 0)-(xDim - 1, yDim - 1), pic
-
- CLS
-
- FOR count = 0 TO 320 - 16
- PUT (count, 90), pic, PSET
- FOR nothing = 1 TO 100
- NEXT nothing
- NEXT count
-
- END
-
- pacmanPic:
- DATA 0,0,0,0,0,0,0,0
- DATA 0,0,1,1,1,1,0,0
- DATA 0,1,1,1,2,1,1,0
- DATA 0,1,1,0,0,0,0,0
- DATA 0,1,1,0,0,0,0,0
- DATA 0,1,1,1,1,1,1,0
- DATA 0,0,1,1,1,1,0,0
- DATA 0,0,0,0,0,0,0,0
-
- Storing the pixels as DATA beats doing every one with the PSET command!
- Try changing the picture DATA using the values 0 to 3.
-
- Just by changing yDim and xDim and the DATA you can now design and display a
- bigger or smaller picture.
-
- -------------------------------------------------------------------------------
- Thats all folks!
- ================
- Hope you enjoyed the course - I can honestly say that I enjoyed writing it.
-
- If you have any comments or questions you can E-mail me at my Internet address:
- ┌───────────────────────┐
- │ avw@mickey.iaccess.za │
- └───────────────────────┘
- or you can reach me by snail-mail:
- ┌───────────────────┐
- │ A. van Wyk │
- │ 105 Sidvale Court │
- │ Parow │
- │ 7500 │
- │ Western Cape │
- │ South Africa │
- └───────────────────┘
-
- If you have found the course useful and would like to see further modules, just
- let me know!
- Time allowing and if there is sufficient interest, I will expand on the course.
-
- Cheers for now,
- Andre
-